<script setup lang="tsx">
import { computed, ref, watch } from 'vue';
import { NButton } from 'naive-ui';
import { useFormRules, useNaiveForm } from '@/hooks/common/form';
import { fetchGetDeviceDetail, fetchGetDeviceList } from '@/service/api';
import { deviceTypeRecord } from '@/constants/business';
import { useTable, useTableOperate } from '@/hooks/common/table';

export type DeviceSelectedMac = TicketManageApi.DeviceManage.Device['mac'][];

interface Props {
  deviceSelectedMac: DeviceSelectedMac;
}

const { deviceSelectedMac } = defineProps<Props>();

interface Emits {
  (e: 'submitted', deviceGroupList: TicketManageApi.DeviceManage.Device[]): void;
}

const emit = defineEmits<Emits>();

/** 已选组网设备集合 */
const deviceGroupList = ref<TicketManageApi.DeviceManage.Device[]>([]);

function createDefaultModel(): TicketManageApi.DeviceManage.DeviceSearchParams {
  return {
    current: 1,
    size: 10,
    mac: null
  };
}

type RuleKey = Extract<keyof TicketManageApi.DeviceManage.DeviceSearchParams, 'mac'>;

const { createMACRule } = useFormRules();

const rules: Record<RuleKey, CommonType.WithArray<App.Global.FormRule>> = {
  mac: [createMACRule()]
};

const { columns, data, getData, getDataByPage, loading, mobilePagination, searchParams, resetSearchParams } = useTable({
  immediate: false,
  apiFn: fetchGetDeviceList,
  showTotal: true,
  apiParams: createDefaultModel(),
  columns: () => [
    {
      type: 'selection',
      align: 'center',
      width: 48,
      disabled: row => {
        return deviceGroupList.value.length >= 2 && !deviceGroupList.value.some(item => item.mac === row.mac);
      }
    },
    {
      key: 'account',
      title: '宽带账号',
      align: 'center'
    },
    {
      key: 'mac',
      title: '设备MAC地址',
      align: 'center'
    },
    {
      key: 'type',
      title: '设备类型',
      align: 'center',
      render: row => {
        if (row.type === null) {
          return null;
        }
        const deviceType = deviceTypeRecord[row.type];

        return deviceType;
      }
    },
    {
      key: 'deviceCity',
      title: '所在地域',
      align: 'center'
    }
  ]
});

const deviceGroupColumns = computed(() => {
  let c = [...columns.value];
  c = c.filter(item => item.type !== 'selection');
  c.push({
    key: 'operate',
    title: '操作',
    align: 'center',
    width: 130,
    render: (row: TicketManageApi.DeviceManage.Device) => (
      <div class="flex-center gap-8px">
        <NButton type="error" ghost size="small" onClick={() => handleDelete(row.mac!)}>
          删除
        </NButton>
      </div>
    )
  });
  return c;
});

const { formRef, validate, restoreValidation } = useNaiveForm();

const visible = defineModel<boolean>('visible', {
  default: false
});

const { checkedRowKeys } = useTableOperate<
  TicketManageApi.DeviceManage.Device,
  TicketManageApi.DeviceManage.Device['mac']
>(data, getData);

async function handleCheckedRowKeys() {
  setSelectedDeviceDetail();
}

function handleDelete(mac: string) {
  const index = checkedRowKeys.value.findIndex(item => item === mac);
  checkedRowKeys.value.splice(index, 1);
  deviceGroupList.value = deviceGroupList.value.filter(item => item.mac !== mac);
}

function closeModal() {
  visible.value = false;
}

async function search() {
  await validate();
  getDataByPage();
}

function handleInitData() {
  Object.assign(searchParams, createDefaultModel());
  checkedRowKeys.value = [...deviceSelectedMac];
  setSelectedDeviceDetail();
}

/** 为勾选的设备 ID 获取详情内容 */
async function setSelectedDeviceDetail() {
  if (checkedRowKeys.value.length === 0) {
    deviceGroupList.value = [];
    return;
  }
  try {
    const fetchs = checkedRowKeys.value.map(mac => fetchGetDeviceDetail(mac!));
    const details = await Promise.all(fetchs);
    deviceGroupList.value = details.filter(res => res.data).map(res => res.data!);
  } catch {
    window.$message?.error('获取设备详情失败');
  }
}

async function handleSubmit() {
  if (deviceGroupList.value.length === 2) {
    emit('submitted', deviceGroupList.value);
    closeModal();
  } else {
    window.$message?.warning('请选择2台设备');
  }
}

watch(visible, () => {
  if (visible.value) {
    handleInitData();
    restoreValidation();
    getData();
  }
});
</script>

<template>
  <NModal v-model:show="visible" title="选择组网设备" :mask-closable="false" preset="card" auto-focus class="w-1000px">
    <div class="min-h-500px flex-col-stretch gap-16px overflow-hidden">
      <NGrid :cols="1">
        <NGi>
          <div class="p-y-16px text-18px">设备列表</div>
          <NForm ref="formRef" :model="searchParams" :rules="rules" label-placement="left">
            <NGrid :cols="3">
              <NFormItemGi label="设备MAC地址" path="mac" class="pr-24px">
                <NInput v-model:value="searchParams.mac" placeholder="请输入设备MAC地址" />
              </NFormItemGi>
              <NFormItemGi :offset="1">
                <NSpace class="w-full" justify="end">
                  <NButton size="small" @click="resetSearchParams">
                    <template #icon>
                      <icon-local-ic-round-refresh class="text-icon" />
                    </template>
                    重置
                  </NButton>
                  <NButton size="small" type="primary" ghost @click="search">
                    <template #icon>
                      <icon-local-ic-round-search class="text-icon" />
                    </template>
                    搜索
                  </NButton>
                </NSpace>
              </NFormItemGi>
            </NGrid>
          </NForm>
          <NCard :bordered="false" size="small" content-class="p-0!">
            <NDataTable
              v-model:checked-row-keys="checkedRowKeys"
              :columns="columns"
              :data="data"
              size="small"
              :max-height="220"
              :scroll-x="800"
              :loading="loading"
              remote
              :row-key="row => row.mac"
              :pagination="mobilePagination"
              class="sm:h-full"
              @update:checked-row-keys="handleCheckedRowKeys"
            />
          </NCard>
        </NGi>
        <NGi>
          <div class="p-y-16px text-18px">已选设备</div>
          <NCard :bordered="false" size="small" content-class="p-0!">
            <NDataTable
              :columns="deviceGroupColumns"
              :data="deviceGroupList"
              size="small"
              :min-height="128"
              :scroll-x="800"
              :row-key="row => row.mac"
              class="deviceGroupTable"
            >
              <template #empty>
                <div class="p-y-16px text-center text-14px">请选择两台设备</div>
              </template>
            </NDataTable>
          </NCard>
        </NGi>
      </NGrid>
    </div>
    <template #footer>
      <NSpace justify="end">
        <NButton size="small" class="mt-16px" @click="closeModal">取消</NButton>
        <NButton type="primary" size="small" class="mt-16px" :loading="loading" @click="handleSubmit">确认</NButton>
      </NSpace>
    </template>
  </NModal>
</template>

<style lang="scss" scoped>
:deep() {
  .deviceGroupTable {
    .n-data-table-empty {
      --at-apply: 'min-h-[90px]! p-0!';
    }
  }
}
</style>
